package org.vaadinpa.logic.commands;

import org.vaadinpa.Conf;
import org.vaadinpa.data.NewsItem;
import org.vaadinpa.data.Planet;
import org.vaadinpa.data.Resource;
import org.vaadinpa.data.Ship;
import org.vaadinpa.exceptions.NotEnoughFundsException;
import org.vaadinpa.logic.Command;
import org.vaadinpa.logic.CommandHandler;

public class ShipBuildCommand extends Command implements Cloneable {

	public final int eta;
	public int traveled;

	public final Ship shipClass;
	public final int num;

	public ShipBuildCommand(Planet from, Ship type, int num) throws NotEnoughFundsException {
		super(from);

		shipClass = type;
		this.num = num;

		eta = Conf.ETA_SHIP_BUILD[shipClass.getType().ordinal()];

		// withdraw resources
		int metal = shipClass.getPrice(Resource.METAL) * num;
		int crystal = shipClass.getPrice(Resource.CRYSTAL) * num;
		int gold = shipClass.getPrice(Resource.GOLD) * num;
		planet.withdrawFunds(metal, crystal, gold);
	}

	@Override
	public void execute() {

		traveled++;
		if (traveled != eta) {
			// not done yet
			ShipBuildCommand clone = (ShipBuildCommand) clone();
			CommandHandler.handle(clone);

		} else {

			// build ships
			int existing = planet.homeFleet.get(shipClass);
			planet.homeFleet.put(shipClass, existing + num);

			NewsItem i = new NewsItem("Ship build complete", "Construction of " + num + " ship of class "
					+ shipClass.getName() + " was completed");
			planet.addNews(i);
		}
	}

	@Override
	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void cancel() {
		double returnRate = traveled == 0 ? 1.0 : Conf.REFUND_SHIP_BUILD;

		// return funds
		int metal = (int) (shipClass.getPrice(Resource.METAL) * num * returnRate);
		int crystal = (int) (shipClass.getPrice(Resource.CRYSTAL) * num * returnRate);
		int gold = (int) (shipClass.getPrice(Resource.GOLD) * num * returnRate);
		planet.depositFunds(metal, crystal, gold);

		NewsItem i = new NewsItem("Ship build canceled", "Construction of " + num + " ship of class "
				+ shipClass.getName() + " was canceled, funds have been returned");
		planet.addNews(i);
	}

	@Override
	public String getDescription() {
		return "Building " + num + " " + shipClass.getName() + ", ETA " + (eta - traveled) + " ticks";
	}

	@Override
	public String getName() {
		return "Ship build";
	}

	@Override
	public void serialize(StringBuilder sb) {
		super.serializeBase(sb);

		sb.append("<eta>" + eta + "</eta>");
		sb.append("<num>" + num + "</num>");
		sb.append("<traveled>" + traveled + "</traveled>");
		sb.append("<ship>" + shipClass.getName() + "</ship>");
		sb.append("</" + this.getClass().getSimpleName() + ">");
	}
}
